package com.exrobot.module.rbt.mq.consumer.order;

import com.alibaba.fastjson.JSON;
import com.exrobot.framework.common.util.date.LocalDateTimeUtils;
import com.exrobot.framework.common.util.object.BeanUtils;
import com.exrobot.module.rbt.controller.admin.order.vo.OrderSaveReqVO;
import com.exrobot.module.rbt.controller.admin.orderitem.vo.OrderItemPageReqVO;
import com.exrobot.module.rbt.controller.admin.robottask.vo.RobotTaskSaveReqVO;
import com.exrobot.module.rbt.controller.app.vo.CommonTaskVO;
import com.exrobot.module.rbt.dal.dataobject.canteeninfo.CanteenInfoDO;
import com.exrobot.module.rbt.dal.dataobject.order.OrderDO;
import com.exrobot.module.rbt.dal.dataobject.orderitem.OrderItemDO;
import com.exrobot.module.rbt.dal.dataobject.robotinfo.RobotInfoDO;
import com.exrobot.module.rbt.dal.dataobject.robottask.RobotTaskDO;
import com.exrobot.module.rbt.enums.RbtOrderStatusEnum;
import com.exrobot.module.rbt.enums.RbtTaskStatusEnum;
import com.exrobot.module.rbt.enums.RbtTaskTypeEnum;
import com.exrobot.module.rbt.framework.util.CommonUtils;
import com.exrobot.module.rbt.mq.message.order.OrderItemMessage;
import com.exrobot.module.rbt.mq.message.order.OrderMessage;
import com.exrobot.module.rbt.service.canteeninfo.CanteenInfoService;
import com.exrobot.module.rbt.service.mqtt.MqttMessageService;
import com.exrobot.module.rbt.service.order.OrderService;
import com.exrobot.module.rbt.service.robotScheduler.RobotSchedulerService;
import com.exrobot.module.rbt.service.robottask.RobotTaskService;
import jakarta.annotation.Resource;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 针对 {@link OrderMessage} 的消费者
 *
 * @author wf
 */
@Component
@Slf4j
public class OrderSendConsumer {

    @Resource
    private OrderService orderService;

    @Resource
    private RobotTaskService taskService;

    @Resource
    private RobotSchedulerService schedulerService;

    @Resource
    private CanteenInfoService canteenInfoService;

    @Resource
    private MqttMessageService mqttMessageService;

    @EventListener
    @Async // Spring Event 默认在 Producer 发送的线程，通过 @Async 实现异步
    public void onMessage(OrderMessage orderSendMessage) {
        log.info("[RedisMQ-订单]接收消息内容：{}", JSON.toJSONString(orderSendMessage));
        if(StringUtil.isNotBlank(orderSendMessage.getArea())) {
            orderSendMessage.setArea(orderSendMessage.getArea().replace("区",":"));
        }
        String point = CommonUtils.getPointByAddress(orderSendMessage.getArea(),orderSendMessage.getFloor(),orderSendMessage.getPoint());
        List<OrderItemDO> itemVOS = new ArrayList<>();
        for (OrderItemMessage item : orderSendMessage.getItems()) {
            Long menuSn = orderSendMessage.getOrderType().equals(1) ? 0L : item.getMenuSn(); //外卖订单所有菜单都为0L
            for (int i = 0; i < item.getNum(); i++) {
                OrderItemDO itemDO = new OrderItemDO();
                itemDO.setOrderSn(orderSendMessage.getOrderSn());
                itemDO.setCanteenSn(orderSendMessage.getCanteenSn());
                itemDO.setMenuSn(menuSn);
                itemDO.setStatus(RbtOrderStatusEnum.SALE.getVal());
                itemDO.setMealTimes(CommonUtils.getMealTime(LocalDateTime.now()));
                itemDO.setCreateTime(LocalDateTime.now());
                itemVOS.add(itemDO);
            }
        }
        OrderSaveReqVO orderSaveReqVO = BeanUtils.toBean(orderSendMessage,OrderSaveReqVO.class,item->{
            item.setPoint(point);
            item.setCheckCode(orderSendMessage.getCode());
            item.setItemDOList(itemVOS);
        });
        OrderDO orderDO = orderService.createOrder(orderSaveReqVO);
        if(orderDO != null) {
          savePrepareTask(orderSaveReqVO);
        } else {
            log.error("[MQ消息] - 创建订单失败");
        }
    }

    private void savePrepareTask(OrderSaveReqVO orderSaveReqVO) {
        CanteenInfoDO canteenInfoDO = canteenInfoService.getCanteenInfoBySn(orderSaveReqVO.getCanteenSn());
        if (canteenInfoDO == null) {
            log.error("[MQ消息] - 餐厅({})信息不存在", orderSaveReqVO.getCanteenSn());
            return;
        }
        String point = canteenInfoDO.getPoint();
        RobotInfoDO robotInfoDO = schedulerService.orderMatchRobot(CommonUtils.getFloorByPoint(point), orderSaveReqVO.getItemDOList());
        if (robotInfoDO == null) {
            log.error("[MQ消息] - 订单({})未匹配到车辆", orderSaveReqVO.getOrderSn());
            return;
        }
        RobotTaskSaveReqVO saveReqVO = new RobotTaskSaveReqVO();
        saveReqVO.setTaskType(RbtTaskTypeEnum.PLACE.getTypeVal());
        saveReqVO.setRobotSn(robotInfoDO.getSn());
        saveReqVO.setStatus(RbtTaskStatusEnum.DISPATCH.getVal());
        saveReqVO.setPoint(point);
        RobotTaskDO robotTask = taskService.createRobotTask(saveReqVO);
        if(robotTask == null) {
            log.error("[MQ消息] - 创建任务失败");
            return;
        }
        //调度中直接发送消息给车辆并更新订单状态
        if(robotTask.getStatus().equals(RbtTaskStatusEnum.DISPATCH.getVal())) {
            orderService.updateOrderItemTaskBySn(orderSaveReqVO.getOrderSn(),robotTask.getTaskNo(),robotInfoDO.getSn(),RbtOrderStatusEnum.TAKE.getVal());
            CommonTaskVO taskVO = new CommonTaskVO();
            taskVO.setTaskId(robotTask.getTaskNo());
            taskVO.setSiteId(point);
            taskVO.setType(robotTask.getTaskType());
            mqttMessageService.sendCommonTask(robotInfoDO.getSn(), Arrays.asList(taskVO));
        }
    }

}
